#pragma once

#include <memory>
#include <QProcess>
#include <QThread>
#include <QtWidgets/QMainWindow>
#include "ui_HDFTool.h"
#include "ui_partition.h"

#include "ioODB.h"
#include "grid.h"
#include "QRedirectStream.h"

class MeshIOWorker;
class ODBToolkit : public QMainWindow
{
    Q_OBJECT

public:
	ODBToolkit(QWidget *parent = Q_NULLPTR);
	~ODBToolkit()
	{
		readerThread.quit();
		readerThread.wait();
	}

	void initUi(int_t opp=0);
	    
    int odbWriter(const H5std_string& fileName);
    int odbReader(const H5std_string& fileName);

    void updateTreeWidget();	

	int_t selectBoundaries(ivector &bcs = ivector());
	int_t selectZones(ivector &zones = ivector());

private:
    Ui::HDFToolClass ui;

    QString fileName;

    //
	KSimuShaPtr simu;

	//
	std::shared_ptr<QRedirectStream> qout;

	//
	QThread readerThread;
	std::shared_ptr<MeshIOWorker> meshIO;
	std::shared_ptr<QProcess> hdfView;

	//
	std::shared_ptr<QDialog> dialog_partition;
	Ui_Dialog_partition ui_partition;

Q_SIGNALS:
	void meshReaderWriter(const QString &fileName, const QString &typeName);

public slots:

	void on_actionNew_triggered();
	void on_actionOpen_triggered();
    void on_actionOpenFOAM_triggered();
	void on_actionCGNS_triggered();
    void on_actionSave_triggered();
	void on_actionClose_triggered();
	void on_actionTecplot_ASCII_triggered();
	void on_actionHDFVIEW_triggered();
	void on_actionDTF_triggered();
	void on_actionCombine_triggered();
	void on_actionPartition_triggered();
	void on_actionRename_triggered();
	void on_actionShowInfo_triggered();
	void on_actionQuit_triggered();
	void on_actionDeleteZone_triggered();

	void on_treeWidget_rightClicked(const QPoint&);
	void on_treeWidget_itemChanged(QTreeWidgetItem *, int);

	void onProcess_readyRead();

	void onThread_finished(const QString &pipe, int status);
};

class MeshIOWorker : public QObject
{
	Q_OBJECT
public:
	MeshIOWorker(ODBToolkit* parent = nullptr, KSimuShaPtr sim = nullptr)
		: mainWin(parent), simu(sim){};

	~MeshIOWorker() {};

private:
	KSimuShaPtr simu;
	ODBToolkit *mainWin;

public slots:
	void meshReaderWriter(const QString &fileName, const QString &typeName);

signals:
	void showMessage(const QString &text, int timeout = 0);
	void finished(const QString &pipe, int status);
};
